import { BaseService, CoolCommException } from '@cool-midway/core';
import { Inject, Provide } from '@midwayjs/core';
import { InjectEntityModel, InjectDataSource } from '@midwayjs/typeorm';
import { Repository, DataSource } from 'typeorm';
import { PayOrderEntity } from '../entity/order';
import { PayPaymentEntity } from '../entity/payment';
import { PayBalanceEntity } from '../entity/balance';
import { PayBalanceLogEntity } from '../entity/balanceLog';
import { PayBalanceService } from './balance';
import * as moment from 'moment';
import { PluginService } from '../../plugin/service/info';
import { UserWxService } from '../../user/service/wx';
import { BillingConfigEntity } from '../../billing/entity/config';

/**
 * 支付模块-订单服务
 */
@Provide()
export class PayOrderService extends BaseService {
  @InjectEntityModel(PayOrderEntity)
  payOrderEntity: Repository<PayOrderEntity>;

  @InjectEntityModel(PayPaymentEntity)
  payPaymentEntity: Repository<PayPaymentEntity>;

  @InjectEntityModel(PayBalanceEntity)
  payBalanceEntity: Repository<PayBalanceEntity>;

  @InjectEntityModel(PayBalanceLogEntity)
  payBalanceLogEntity: Repository<PayBalanceLogEntity>;

  @InjectEntityModel(BillingConfigEntity)
  billingConfigEntity: Repository<BillingConfigEntity>;

  @InjectDataSource()
  dataSource: DataSource;

  @Inject()
  payBalanceService: PayBalanceService;

  @Inject()
  ctx;

  @Inject()
  pluginService: PluginService;

  @Inject()
  userWxService: UserWxService;

  // 创建微信支付订单
  async createWxPayOrder({ out_trade_no, description, amount }) {
    const userId = this.ctx.user.id;

    // 获取用户的openid
    const openid = await this.userWxService.getOpenid(userId);

    // 获得微信支付 SDK 实例
    const instance = await this.pluginService.invoke('pay-wx', 'getInstance');

    // 获得配置
    const _config = await this.pluginService.invoke('pay-wx', 'getConfig');

    console.log('插件配置', _config);

    const _res = await instance.transactions_jsapi({
      description: description,
      out_trade_no: out_trade_no,
      notify_url: `https://haiqilink.com/api/app/pay/order/wxNotify`,
      amount: {
        total: amount,
      },
      payer: {
        openid: openid,
      },
    });

    return _res.data;
  }

  /**
   * 创建充值余额订单
   */
  async createRechargeOrder(userId: number, amount: number, title?: string) {
    const orderNo = this.generateOrderNo();
    const order = new PayOrderEntity();
    order.userId = userId;
    order.orderNo = orderNo;
    order.title = title || `余额充值 ${amount}元`;
    order.description = `用户充值账户余额 ${amount}元`;
    order.orderType = 0; // 充值余额
    order.amount = amount;
    order.rechargeAmount = amount;
    order.status = 0; // 待支付
    order.paymentMethod = 0; // 默认微信支付

    await this.payOrderEntity.save(order);

    return this.createWxPayOrder({
      out_trade_no: orderNo,
      amount: amount * 100,
      description: order.description,
    });
  }

  /**
   * 创建购买流量订单
   */
  async createTrafficOrder(
    userId: number,
    amount: number
    // trafficSize: number,
    // validDays: number
  ) {
    const orderNo = this.generateOrderNo();
    const order = new PayOrderEntity();
    order.userId = userId;
    order.orderNo = orderNo;
    // order.title = `购买流量包 ${trafficSize}MB`;
    // order.description = `购买流量包 ${trafficSize}MB，有效期${validDays}天`;
    order.orderType = 1; // 购买流量
    order.amount = amount;
    // order.trafficSize = trafficSize;
    // order.trafficValidDays = validDays;
    order.status = 0; // 待支付

    return await this.payOrderEntity.save(order);
  }

  /**
   * 创建电话通知充值订单
   */
  async createCallOrder(userId: number, amount: number) {
    const orderNo = this.generateOrderNo();
    const order = new PayOrderEntity();
    order.userId = userId;
    order.orderNo = orderNo;
    // order.title = `电话通知充值 ${callMinutes}分钟`;
    order.description = `电话通知充值 ${amount}元`;
    order.orderType = 2; // 电话通知充值
    order.amount = amount;
    // order.callMinutes = callMinutes;
    order.status = 0; // 待支付

    await this.payOrderEntity.save(order);

    return this.createWxPayOrder({
      out_trade_no: orderNo,
      amount: amount * 100,
      description: order.description,
    });
  }

  /**
   * 创建物联网卡充值订单
   */
  async createIotCardOrder(
    userId: number,
    amount: number,
    iccid: string,
    trafficSize: number
  ) {
    const orderNo = this.generateOrderNo();
    const order = new PayOrderEntity();
    order.userId = userId;
    order.orderNo = orderNo;
    order.title = `物联网卡充值 ${trafficSize}MB`;
    order.description = `物联网卡(${iccid})充值流量 ${trafficSize}MB`;
    order.orderType = 3; // 物联网卡充值
    order.amount = amount;
    order.iccid = iccid;
    order.iotTrafficSize = trafficSize;
    order.status = 0; // 待支付

    return await this.payOrderEntity.save(order);
  }

  /**
   * 创建短信通知充值订单
   */
  async createSmsOrder(userId: number, amount: number) {
    const orderNo = this.generateOrderNo();
    const order = new PayOrderEntity();
    order.userId = userId;
    order.orderNo = orderNo;
    // order.title = `短信通知充值 ${smsCount}条`;
    order.description = `短信通知充值${amount}元`;
    order.orderType = 4; // 短信通知充值
    order.amount = amount;
    // order.smsCount = smsCount;
    order.status = 0; // 待支付

    await this.payOrderEntity.save(order);

    return this.createWxPayOrder({
      out_trade_no: orderNo,
      amount: amount * 100,
      description: order.description,
    });
  }

  // 创建物联网卡年费充值
  async createIotYearOrder(userId: number) {
    const orderNo = this.generateOrderNo();
    const order = new PayOrderEntity();

    // 从billing_config表获取id为3的配置，对应的unitPrice就是物联网卡年费
    const config = await this.billingConfigEntity.findOneBy({
      id: 3,
    });

    const amount = config.unitPrice;

    order.userId = userId;
    order.orderNo = orderNo;
    order.title = `物联网卡年费充值`;
    order.description = `物联网卡(年费充值${amount}元`;
    order.orderType = 5; // 物联网卡年费充值
    order.amount = amount;
    order.iccid = '';
    order.status = 0; // 待支付

    await this.payOrderEntity.save(order);

    return this.createWxPayOrder({
      out_trade_no: orderNo,
      amount: amount * 100,
      description: order.description,
    });
  }

  /**
   * 支付订单
   */
  async payOrder(orderId: number, paymentMethod: number, paymentInfo?: any) {
    const queryRunner = this.dataSource.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();

    try {
      const order = await queryRunner.manager.findOne(PayOrderEntity, {
        where: { id: orderId },
      });

      if (!order) {
        throw new CoolCommException('订单不存在');
      }

      if (order.status !== 0) {
        throw new CoolCommException('订单状态不正确');
      }

      // 创建支付记录
      const payment = new PayPaymentEntity();
      payment.userId = order.userId;
      payment.orderId = order.id;
      payment.paymentNo = this.generatePaymentNo();
      payment.amount = order.amount;
      payment.paymentMethod = paymentMethod;
      payment.status = 2; // 支付成功
      payment.payTime = new Date();
      payment.completeTime = new Date();

      if (paymentInfo) {
        payment.thirdPartyNo = paymentInfo.thirdPartyNo;
        payment.payChannel = paymentInfo.payChannel;
        payment.payIp = paymentInfo.payIp;
        payment.deviceInfo = paymentInfo.deviceInfo;
        payment.thirdPartyResponse = paymentInfo.thirdPartyResponse;
      }

      // 如果是余额支付，需要扣减用户余额
      if (paymentMethod === 2) {
        const balanceInfo = await this.payBalanceService.deductBalance(
          order.userId,
          order.amount,
          order.id,
          order.orderNo,
          `${this.getOrderTypeText(order.orderType)}支付`,
          order.orderType,
          queryRunner
        );
        payment.beforeBalance = balanceInfo.beforeBalance;
        payment.afterBalance = balanceInfo.afterBalance;
      }

      await queryRunner.manager.save(payment);

      // 更新订单状态
      order.status = 1; // 已支付
      order.payTime = new Date();
      order.paymentMethod = paymentMethod;
      await queryRunner.manager.save(order);

      // 如果是充值余额订单，需要增加用户余额
      if (order.orderType === 0) {
        await this.payBalanceService.addBalance(
          order.userId,
          order.rechargeAmount,
          order.id,
          order.orderNo,
          '余额充值',
          0,
          queryRunner
        );
      }

      await queryRunner.commitTransaction();
      return { order, payment };
    } catch (error) {
      await queryRunner.rollbackTransaction();
      throw error;
    } finally {
      await queryRunner.release();
    }
  }

  /**
   * 取消订单
   */
  async cancelOrder(orderId: number) {
    const order = await this.payOrderEntity.findOne({
      where: { id: orderId },
    });

    if (!order) {
      throw new CoolCommException('订单不存在');
    }

    if (order.status !== 0) {
      throw new CoolCommException('只能取消待支付订单');
    }

    order.status = 2; // 已取消
    order.cancelTime = new Date();

    return await this.payOrderEntity.save(order);
  }

  /**
   * 获取用户订单列表
   */
  async getUserOrders(userId: number, page: number = 1, size: number = 10) {
    const [list, total] = await this.payOrderEntity.findAndCount({
      where: { userId },
      order: { createTime: 'DESC' },
      skip: (page - 1) * size,
      take: size,
    });

    return {
      list,
      total,
      page,
      size,
    };
  }

  /**
   * 生成订单号
   */
  private generateOrderNo(): string {
    const timestamp = moment().format('YYYYMMDDHHmmss');
    const random = Math.floor(Math.random() * 10000)
      .toString()
      .padStart(4, '0');
    return `ORD${timestamp}${random}`;
  }

  /**
   * 生成支付流水号
   */
  private generatePaymentNo(): string {
    const timestamp = moment().format('YYYYMMDDHHmmss');
    const random = Math.floor(Math.random() * 10000)
      .toString()
      .padStart(4, '0');
    return `PAY${timestamp}${random}`;
  }

  /**
   * 获取订单类型文本
   */
  private getOrderTypeText(orderType: number): string {
    const types = [
      '充值余额',
      '购买流量',
      '电话通知充值',
      '物联网卡充值',
      '短信通知充值',
    ];
    return types[orderType] || '未知类型';
  }
}
